import time
from flask import Flask, request, jsonify, Response, render_template
import csv
import io
import smtplib
from email.mime.text import MIMEText
from email.header import Header


import asyncio
import json
import sys
import traceback
import unittest
import uuid
from io import StringIO
from typing import Dict, List
from unittest.mock import MagicMock, patch
 
import aiohttp
import requests
import os
import logging
from sms_util import send_bulk_sms
from werkzeug.exceptions import RequestEntityTooLarge


app = Flask(__name__)
app.config['MAX_CONTENT_LENGTH'] = 32 * 1024 * 1024  # 16MB 上传限制

# 初始化 logger
logging.basicConfig(level=logging.INFO, format='%(asctime)s %(levelname)s %(message)s')
logger = logging.getLogger(__name__)

# 全局初始化 GoogleEmail 实例
try:
    from google_email import GoogleEmail
    client_secret_path = os.environ.get("GMAIL_CLIENT_SECRET_PATH", "/tmp/client_secret_star_ktv.json")
    token_path = os.environ.get("GMAIL_TOKEN_PATH", "/tmp/token_star_ktv.json")
    email_sender = GoogleEmail(
        client_secret_path=client_secret_path,
        token_path=token_path,
        headless=True
    )
except Exception as e:
    email_sender = None
    logger.error(f"GoogleEmail 初始化失败: {str(e)}")

# 添加邮件发送接口（Flask版本）
@app.route("/chat/send_gmail", methods=["POST"])
def send_gmail():
    try:
        # 兼容 application/json 和其他 content-type
        data = request.get_json(force=True, silent=True)
        if not isinstance(data, dict):
            try:
                data = json.loads(request.data)
            except Exception:
                data = {}
        subject = data.get("subject", "")
        body = data.get("body", "")
        to_recipients = data.get("to", "")
        cc_recipients = data.get("cc", None)
        bcc_recipients = data.get("bcc", None)
        attachment_path = data.get("attachment", None)
        sender_name = data.get("sender_name", "")
        sender_email = data.get("sender_email", "")
        retry_times = data.get("retry_times", 3)
        retry_interval = data.get("retry_interval", 5)
        timeout = data.get("timeout", 30)
        if not subject or not body or not to_recipients:
            return jsonify({"code": 1, "msg": "邮件主题、内容和收件人不能为空"})
        if email_sender is None:
            return jsonify({"code": 1, "msg": "邮件服务未初始化"})
        email_sender.send(
            subject=subject,
            body=body,
            to_recipients=to_recipients,
            cc_recipients=cc_recipients,
            bcc_recipients=bcc_recipients,
            attachment_path=attachment_path,
            sender_name=sender_name,
            sender_email=sender_email,
            retry_times=retry_times,
            retry_interval=retry_interval,
            timeout=timeout
        )
        logger.info(f"邮件发送成功，收件人: {to_recipients}, 主题: {subject}")
        return jsonify({"code": 0, "msg": "邮件发送成功"})
    except Exception as e:
        logger.error(f"邮件发送失败: {str(e)}, {traceback.format_exc()}")
        return jsonify({"code": 1, "msg": f"邮件发送失败: {str(e)}"})

# 添加邮件发送接口OPTIONS请求处理（Flask版本）
@app.route("/chat/send_gmail", methods=["OPTIONS"])
def options_send_gmail():
    return Response(status=200)

@app.route('/index', methods=['GET'])
@app.route('/', methods=['GET'])
def send_gmail_page():
    return render_template('send_messages.html')

@app.route('/chat/send_sms_batch', methods=['POST'])
def send_sms_batch():
    try:
        message_body = request.form.get('body', '')
        file = request.files.get('file')
        if not message_body or not file:
            return jsonify({'code': 1, 'msg': '短信内容和文件不能为空'})
        # 解析csv/excel文件，提取手机号
        phones = []
        filename = file.filename.lower()
        if filename.endswith('.csv'):
            stream = io.StringIO(file.stream.read().decode('utf-8', errors='ignore'))
            reader = csv.reader(stream)
            header = next(reader, None)
            phone_idx = None
            if header:
                for i, col in enumerate(header):
                    if 'phone' in col.lower() or 'mobile' in col.lower():
                        phone_idx = i
                        logger.info(f"找到手机号列: {phone_idx}")
                        break
                if phone_idx is None:
                    return jsonify({'code': 1, 'msg': '未找到手机号列'})
            for row in reader:
                if not row or (phone_idx is not None and (row[phone_idx].strip() == '' or row[phone_idx].strip() is None)):
                    continue
                if phone_idx is not None:
                    phone = row[phone_idx].strip()
                    if phone:
                        phones.append(phone)
        else:
            # 解析excel文件
            import openpyxl
            wb = openpyxl.load_workbook(file)
            ws = wb.active
            phone_col = None
            for i, cell in enumerate(next(ws.iter_rows(min_row=1, max_row=1))):
                if 'phone' in str(cell.value).lower():
                    phone_col = i
                    break
            for row in ws.iter_rows(min_row=2):
                if phone_col is not None:
                    cell = row[phone_col]
                    phone = str(cell.value).strip() if cell.value else ''
                    if phone:
                        phones.append(phone)
        if not phones:
            return jsonify({'code': 1, 'msg': '未解析到有效手机号'})
        # 群发短信
        send_bulk_sms(phones, message_body)
        logger.info(f"群发短信成功，数量: {len(phones)}")
        return jsonify({'code': 0, 'msg': f'群发短信成功，数量: {len(phones)}'})
    except Exception as e:
        logger.error(f"群发短信失败: {str(e)}, {traceback.format_exc()}")
        return jsonify({'code': 1, 'msg': f'群发短信失败: {str(e)}'})

@app.route('/chat/send_messages_batch', methods=['POST'])
def send_gmail_batch():
    try:
        subject = request.form.get('subject', '')
        body = request.form.get('body', '')
        file = request.files.get('file')
        send_email_checked = request.form.get('send_email', 'off') == 'on'
        send_sms_checked = request.form.get('send_sms', 'off') == 'on'
        if not body or not file:
            return jsonify({'code': 1, 'msg': '邮件/短信内容和文件不能为空'})
        filename = file.filename.lower()
        emails = []
        phones = []
        if filename.endswith('.csv'):
            stream = io.StringIO(file.stream.read().decode('utf-8', errors='ignore'))
            reader = csv.reader(stream)
            header = next(reader, None)
            email_idx = phone_idx = None
            if header:
                for i, col in enumerate(header):
                    if 'email' in col.lower():
                        email_idx = i
                    if 'phone' in col.lower():
                        phone_idx = i
                if send_email_checked and email_idx is None:
                    return jsonify({'code': 1, 'msg': '未找到邮箱列'})
                if send_sms_checked and phone_idx is None:
                    return jsonify({'code': 1, 'msg': '未找到手机号列'})
            for row in reader:
                if send_email_checked and email_idx is not None:
                    email = row[email_idx].strip() if len(row) > email_idx else ''
                    if email:
                        emails.append(email)
                if send_sms_checked and phone_idx is not None:
                    phone = row[phone_idx].strip() if len(row) > phone_idx else ''
                    if phone:
                        phones.append(phone)
        else:
            import openpyxl
            wb = openpyxl.load_workbook(file)
            ws = wb.active
            email_col = phone_col = None
            for i, cell in enumerate(next(ws.iter_rows(min_row=1, max_row=1))):
                if 'email' in str(cell.value).lower():
                    email_col = i
                if 'phone' in str(cell.value).lower():
                    phone_col = i
            for row in ws.iter_rows(min_row=2):
                if send_email_checked and email_col is not None:
                    cell = row[email_col]
                    email = str(cell.value).strip() if cell.value else ''
                    if email:
                        emails.append(email)
                if send_sms_checked and phone_col is not None:
                    cell = row[phone_col]
                    phone = str(cell.value).strip() if cell.value else ''
                    if phone:
                        phones.append(phone)
        result_msgs = []
        if send_email_checked:
            if not emails:
                result_msgs.append('未解析到有效收件人邮箱')
            elif email_sender is None:
                result_msgs.append('邮件服务未初始化')
            else:
                success_count = 0
                for email in emails:
                    try:
                        logger.info(f"开始发送邮件: {email}")
                        result = email_sender.send(
                            subject=subject,
                            body=body,
                            to_recipients=email
                        )
                        if result == 1: success_count += 1
                        time.sleep(1)
                    except Exception as e:
                        logger.error(f"发送邮件失败: {email}, {str(e)}")
                result_msgs.append(f'群发邮件成功，应发：{len(emails)}  数量: {success_count}')
        if send_sms_checked:
            if not phones:
                result_msgs.append('未解析到有效手机号')
            else:
                send_bulk_sms(phones, body)
                result_msgs.append(f'群发短信成功，数量: {len(phones)}')
        return jsonify({'code': 0, 'msg': '；'.join(result_msgs)})
    except Exception as e:
        logger.error(f"群发邮件/短信失败: {str(e)}, {traceback.format_exc()}")
        return jsonify({'code': 1, 'msg': f'群发邮件/短信失败: {str(e)}'})

@app.errorhandler(RequestEntityTooLarge)
def handle_file_too_large(e):
    return jsonify({'code': 1, 'msg': '上传文件过大，请压缩图片或分批上传（建议单次不超过32MB）'}), 413

if __name__ == "__main__":
    host = os.environ.get("SERVER_HOST", "0.0.0.0")
    port = int(os.environ.get("SERVER_PORT", 5000))
 
    logger.info(f"正在启动简单AI Shop服务，地址: {host}:{port}")
    logger.info(f"API接口: http://localhost:{port}/chat/completions")
    logger.info(f"API接口: http://localhost:{port}/chat/knowledge/insert")
    logger.info(f"API文档: http://localhost:{port}/docs")
    logger.info("CORS已配置，允许所有来源的跨域请求")
    app.run(host=host, port=port)